package gamagora.game.entity.player
{
	import gamagora.game.resources.OSImages;
	import gamagora.game.states.OSPlayState;
	
	import org.flixel.FlxObject;
	import org.flixel.FlxSprite;
	import org.flixel.FlxText;

	public class OSPlayerAnimation 
	{
		public static const IDLE:String = "idle"; 
		public static const RUN:String	= "run";
		public static const ON_WALL:String = "on_wall"; 
		
		public static const JUMP1_UP:String = "jump1_up";
		public static const JUMP1_DOWN:String = "jump1_down";
		public static const JUMP1_GROUND:String = "jump1_ground";
		
		public static const JUMP2_TAKEOFF:String = "jump2_takeoff";
		public static const JUMP2_UP:String = "jump2_up";
		public static const JUMP2_TOP:String = "jump2_top";
		public static const JUMP2_DOWN:String = "jump2_down";
		
		public static const RUN_TO_IDLE:String	= "run_to_idle";
		public static const IDLE_TO_RUN:String	= "idle_to_run";
		
		public static const RUN_TO_PUSH_BOX:String = "run_to_push_box";
		public static const PUSH_BOX_TO_IDLE:String = "push_box_to_idle";
		public static const PUSH_BOX:String = "push_box";
		
		private static const ANIMATION_SPEED:Number = 2.0;
		
		private var _player:OSPlayer;
		private var _debugAnim:FlxText;
		private var _velX:Number;
		private var _velY:Number;
		private var _xMove:Boolean;
		private var _yMove:Boolean;
		private var _vertJump:Boolean;
		private var _horJump:Boolean;
		
		public function OSPlayerAnimation(player:OSPlayer)
		{
			_player = player;
			_player.offset.x += 44;
			_player.offset.y += 70;
			
			// Affichage
			_player.loadGraphic(OSImages.MONKEY3, true, true, 128, 128);
			
			// Animation
			_player.addAnimation(IDLE, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], 10 * ANIMATION_SPEED);
			_player.addAnimation(RUN, [85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109], 20 * ANIMATION_SPEED);
			
			// Jump 1
			_player.addAnimation(JUMP1_UP, [60, 61, 62, 63, 66, 67, 68], 25 * ANIMATION_SPEED, false);
			_player.addAnimation(JUMP1_DOWN, [69, 70, 71, 72, 73, 74, 75], 30 * ANIMATION_SPEED, false);
			_player.addAnimation(JUMP1_GROUND, [76, 76, 77, 77, 78, 79, 80, 81, 82, 83, 84], 30 * ANIMATION_SPEED, false);
			
			//Wall
			_player.addAnimation(ON_WALL, [127]);
			//_player.addAnimation(JUMP_FROM_WALL, [128, 129, 130, 131, 132, 133], 20 * ANIMATION_SPEED, false);
			
			// Jump 2 extension
			_player.addAnimation(JUMP2_TAKEOFF, [135, 136, 137, 138, 139, 140, 141], 25 * ANIMATION_SPEED, false);
			_player.addAnimation(JUMP2_UP, [142, 143], 10 * ANIMATION_SPEED);
			_player.addAnimation(JUMP2_TOP, [144, 145], 20 * ANIMATION_SPEED, false);
			_player.addAnimation(JUMP2_DOWN, [146, 147, 148], 10 * ANIMATION_SPEED);
			//_player.addAnimation(JUMP2_GROUND, [149, 150, 151, 152, 153, 154], 20 * ANIMATION_SPEED, false);
			
			// Run transitions
			_player.addAnimation(IDLE_TO_RUN, [20, 21, 22, 23, 34, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38], 60 * ANIMATION_SPEED, false);
			_player.addAnimation(RUN_TO_IDLE, [40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58], 20 * ANIMATION_SPEED, false);
		
			//Box
			_player.addAnimation(RUN_TO_PUSH_BOX, [160, 161, 162, 163, 164], 10 * ANIMATION_SPEED, false);
			_player.addAnimation(PUSH_BOX, [165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179], 10 * ANIMATION_SPEED);
			_player.addAnimation(PUSH_BOX_TO_IDLE, [180, 181, 182, 183, 184], 8 * ANIMATION_SPEED, false);
			
			//Play idle
			_player.play(IDLE);
			
			//Debug
			if(OSPlayer.DEBUG)
			{
				_debugAnim = OSPlayState.addDebugText();
			}
		}
		
		public function update():void
		{
			if(OSPlayer.DEBUG)
			{
				_debugAnim.text = "Current animation = " + _player.curAnim.name;
			}
			
			_velX = _player.vel.x;
			_velY = _player.vel.y;
			_xMove = Math.abs(_velX) > 0.01;
			_yMove = Math.abs(_velY) > 0.01;
			
			_player.facing = _velX < 0 ? FlxObject.RIGHT : _velX > 0 ? FlxObject.LEFT : _player.facing;
			
			updateAnimationsMoves();
			updateFinishedAnimations();
		}
		
		public function updateAnimationsMoves():void
		{
			if(_player.onGround || _player.onInclinedGround)
			{
				if(_xMove)
				{
					if(_player.curAnim.name == IDLE)
					{
						_player.play(IDLE_TO_RUN);
					}
					
					if(_player.isMovingBox())
					{
						if(_player.curAnim.name == RUN)
						{
							_player.play(RUN_TO_PUSH_BOX);
						}
					}
					else
					{
						if(_player.curAnim.name == PUSH_BOX)
						{
							_player.play(RUN);
						}
					}
				}
				else 
				{
					if(_player.curAnim.name == RUN)
					{
						_player.play(RUN_TO_IDLE);
					}
					else
					{
						if(_player.curAnim.name == PUSH_BOX)
						{
							_player.play(PUSH_BOX_TO_IDLE);
						}
					}
				}
			}
			else 
			{
				if(_player.canJump)
				{
					if(_player.wallJump)
					{
						_player.play(ON_WALL);
						_player.vel.y *= .98;
					}
				}
				else 
				{
					if(_xMove)
					{
						//Saut de côté
						if(!_horJump && !_vertJump)
						{
							_player.play(JUMP2_TAKEOFF);
							_horJump = true;
						}
					}
					else 
					{
						//Saut vertical
						if(!_vertJump && _velY < 0.1) //Le test sur y évite au joueur de sauter au dessus d'une pente
						{
							_player.play(JUMP1_UP);
							_vertJump = true;
						}
					}
				}
			}
		}
		
		public function updateFinishedAnimations():void
		{
			if(_player.finished)
			{
				switch(_player.curAnim.name)
				{
					case IDLE_TO_RUN:
						if(_player.isMovingBox())
						{
							_player.play(RUN_TO_PUSH_BOX);
						}
						else
						{
							_player.play(_xMove ? RUN : RUN_TO_IDLE);
						}
						break;
					case RUN_TO_IDLE:
						_player.play(_xMove ? IDLE_TO_RUN : IDLE);
						break;
					case RUN_TO_PUSH_BOX:
						_player.play(_xMove ? PUSH_BOX : PUSH_BOX_TO_IDLE);
						break;
					case PUSH_BOX_TO_IDLE:
						_player.play(_xMove ? RUN_TO_PUSH_BOX : IDLE);
						break;
					case JUMP1_UP:
						if(_velY >= 0)
						{
							_player.play(JUMP1_DOWN);
						}
						break;
					case JUMP1_DOWN:
						if(_player.onGround)
						{
							_player.play(JUMP1_GROUND);
						}
						break;
					case JUMP1_GROUND:
						_player.play(IDLE);
						_vertJump = false;
						_horJump = false;
						break;
					case ON_WALL:
						if(_player.onGround)
						{
							_player.play(JUMP1_GROUND);
							_horJump = false;
						}
						break;
					case JUMP2_TAKEOFF:
						_player.play(JUMP2_UP);
						break;
				}
			}

			//Cas spécial pour le Jump 2 qui boucle et dépend de la vitesse
			if(_horJump && !(_player.canJump && _player.wallJump))
			{
				if(_player.onGround)
				{
					_vertJump = false;
					_horJump = false;
					_player.play(_xMove ? RUN : IDLE);
				}
				else 
				{
					if (_velY < -0.2) // Phase montante
					{
						_player.play(JUMP2_UP);
					} 
					else if (_velY > -1 && _velY < 2) // Haut du saut
					{
						if(_player.curAnim.name != JUMP2_TOP)
						{
							_player.play(JUMP2_TOP);
						}
					} 
					else if (_velY > 0.2) // Phase descendante
					{
						_player.play(JUMP2_DOWN);
					}	
				}
			}
			else 
			{
				//Le joueur a sauté sur une pente incliné 
				if(_player.onInclinedGround && (_horJump || _vertJump))
				{
					_vertJump = false;
					_horJump = false;
					_player.play(_xMove ? RUN : IDLE);	
				}
			}
		}
	}
}
